package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 用于测试JDBC通过PreparedStatement解决SQL注入问题
 * 防止SQL注入的步骤:
 * ①定义SQL骨架,先拟定SQL语句,但是涉及到参数部分,则以"?"替换
 * ②调用方法,为SQL骨架传入参数
 */
public class TestSelect3 {
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/tedu?useUnicode=true&characterEncoding=utf8&serverTimeZone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.定义sql语句
        //SQL骨架 → 固定SQL语句的执行意义
        String sql = "SELECT * FROM location WHERE id = ? AND name = ?;";
        //2.创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //3.为SQL骨架传入参数
        /*
         * PrepareStatement 提供了给SQL骨架的"?"参数传入参数值的方法
         * set类型(参数的索引值,参数值)
         * 参数的索引值: 表示SQL骨架中,从左到右第几个"?"
         * SQL骨架中的参数会自动根据类型拼到到骨架中
         */
        ps.setInt(1, 1); // 给第一个"?"传入int类型的参数值 1
        //ps.setString(2, "北京"); //给第二个"?"传入String类型的参数值 北京
        ps.setString(2, "' OR '1'='1"); //给第二个"?"传入String类型的参数值 北京
        //4.通过PreparedStatement调用executeQuery()方法执行查询操作
        rs = ps.executeQuery();
        //5.遍历结果集
        System.out.println(rs.next() == true ? "记录存在!" : "记录不存在!");
        //6.释放资源
        rs.close();
        ps.close();
        conn.close();
    }
}
